//
//  IvanSqliteDB.m
//  YuchBox
//
//  Created by Ivan on 11-10-19.
//  Copyright 2011年 __MyCompanyName__. All rights reserved.
//

#import "IvanSqliteDB.h"
#import "SingletonClassGenerator.h"

#define DATABASE_CREATE_SQL     @"create_yuchbox_111019.sql"
#define DATABASE_FILE_NAME      @"yuchbox.db"

//static const NSString *DATABASE_FILE_NAME   = @"yuchbox.db";
//static const NSString *DATABASE_CREATE_SQL  = @"sqlite/create_yuchbox_111019.sql";

@implementation IvanSqliteDB
SYNTHESIZE_SINGLETON_FOR_CLASS(IvanSqliteDB);
- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
        //assert(TRUE == [self connect]);
    }
    
    return self;
}

- (id)initSingleton
{
    self = [self init];
    return  self;
}

+ (NSString *)getDbFilePath
{
    NSArray *docmentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *dbFilePath = [[docmentPaths objectAtIndex:0] stringByAppendingPathComponent:DATABASE_FILE_NAME];
    
    return dbFilePath;
}

+ (void)createDBEnvironment
{
    NSString *dbFilePath = [IvanSqliteDB getDbFilePath];
    
    NSFileManager * fileMgr = [NSFileManager defaultManager];
    
    if ([fileMgr fileExistsAtPath:dbFilePath]) {
        TTLOGF_INFO(@"check db:%@ [OK]", DATABASE_FILE_NAME);
        return;
    }
    // create db
    NSString * createSqlFilePath = [NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] bundlePath], DATABASE_CREATE_SQL];

    sqlite3 *db;
    if (SQLITE_OK != sqlite3_open([dbFilePath UTF8String], &db)) {
        TTLOGF_ERROR(@"Failed to connect yuchbox database '%s'", sqlite3_errmsg(db));
    }
    
    //NSError *error;// = [[NSError alloc] init];
    NSString *createSql = [NSString stringWithContentsOfFile:createSqlFilePath encoding:NSUTF8StringEncoding error:nil];
    TTLOGF_INFO(@"check db:%@. create new one...", DATABASE_FILE_NAME);
    //TTLOG_INFO(createSql);
    
    if (nil == createSql) {
        TTLOGF_ERROR(@"read the create sql error from <file:%@>", createSqlFilePath);
        return;
    }
    
    char *errorMsg;
    if (SQLITE_OK != sqlite3_exec(db, [createSql UTF8String], nil, nil, &errorMsg)) {
        TTLOGF_ERROR(@"create the database error <error:%s>", errorMsg);
        sqlite3_free(errorMsg);
    }
    TTLOGF_INFO(@"create db:%@ [ok]", DATABASE_FILE_NAME);
    sqlite3_close(db);
}

- (Boolean)connect
{
    if (SQLITE_OK != sqlite3_open([[IvanSqliteDB getDbFilePath] UTF8String], &_db)) {
        TTLOGF_ERROR(@"Failed to connect yuchbox database '%s'", sqlite3_errmsg(_db));
        return NO;
    }
    
    return YES;
}

- (void)closeConnection
{
    sqlite3_close(_db);
}

- (Boolean)checkConnection
{
    //TTLOGF_ERROR(@"Failed to connect yuchbox database '%s'", sqlite3_errmsg(_db));
    return (NULL != _db);
}


- (Boolean)updateWithSql:(NSString *)sql
{
    const char * updtSql = [sql UTF8String];
    char *errorMsg;
    // char * instSql_escaped = sqlite3_mprintf("%Q", instSql);
    int ret = sqlite3_exec(_db, updtSql, nil, nil, &errorMsg);
    if (SQLITE_OK != ret) {
        TTLOGF_ERROR(@"%s", updtSql);
        TTLOGF_ERROR(@"Failed update to database, %s <code: %d>\n", errorMsg, ret);
        sqlite3_free(errorMsg);
        return FALSE;
    }
    
    return TRUE;
}

- (Boolean)insertWithSql:(NSString *)sql
{
    const char * instSql = [sql UTF8String];
    char *errorMsg;
   // char * instSql_escaped = sqlite3_mprintf("%Q", instSql);
    int ret = sqlite3_exec(_db, instSql, nil, nil, &errorMsg);
    if (SQLITE_OK != ret) {
        //TTLOGF_ERROR(@"%s", instSql);
        TTLOGF_ERROR(@"Failed insert to database, %s <code: %d>\n", errorMsg, ret);
        sqlite3_free(errorMsg);
        return FALSE;
    }
    
    return TRUE;
}


//- (BOOL)prepare:(NSString *)sql
//{
//    const char * selcSql = [sql UTF8String];
//    char *errorMsg;
//    
//    sqlite3
//}

- (sqlite3_stmt *)prepareSelect:(NSString *)sql
{
    const char * selcSql = [sql UTF8String];
    
    sqlite3_stmt *statement;
    if (SQLITE_OK == sqlite3_prepare_v2(_db, selcSql, -1, &statement, nil)) {
        return statement;
    } else {
        TTLOGF_ERROR(@"Failed to select from database! %s", selcSql);
    }

    return nil;
}

- (id)selectOneWithSql:(NSString *)sql
{
    return nil;
}

- (UInt64)getLastInsertRowid
{
    return sqlite3_last_insert_rowid(_db);
}
@end
